<?php

use Mapper\MemberModel as MemberMapper;
use Mapper\SparringbuysModel as BuyMapper;
use Mapper\SparringbuydetailModel as BuyDetailMapper;
use Mapper\SparringgameModel as GameMapper;
use Mapper\MemberAvatarModel as MemberAvatarMapper;

class SparringbuysController extends \Base\ApiController {

    /**
     * @desc 看大腿列表
     */
    public function listAction() {
        $request  = $this->getRequest();
        $page     = (int)$request->get('page', 1);
        $perPage  = (int)$request->get('per_page', 15);
        $gameId   = (string)$request->get('game_id');
        $minPrice = (int)$request->get('min_price');
        $maxPrice = (int)$request->get('max_price');
        $gender   = (int)$request->get('gender');
        $time     = (string)$request->get('time');
        $page     = max(1, $page);
        $perPage  = min(30, $perPage);
        $limit    = $perPage;
        $offset   = $limit * ($page - 1);
        $return   = [];

        $where = ['status' => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL, 'begin_time > ?' => time()];

        if(!empty($gameId)) {
            $where['game_id'] = $gameId;
        }

        if($gender === 1 || $gender === 2) {
            $where['gender'] = $gender;
        }

        if($minPrice > 0) {
            $where['price >= ?'] = $minPrice;
        }

        if($maxPrice > 0) {
            $where['price <= ?'] = $maxPrice;
        }

        if(!empty($time)) {
            $timeArr = explode(' ', $time);

            if($timeArr[0] === '今天') {
                $timeStr = date("Y-m-d") . ' ' . $timeArr[1];
            } elseif($timeArr[0] === '明天') {
                $timeStr = date("Y-m-d", strtotime("+1 day")) . ' ' . $timeArr[1];
            } else {
                return $this->response(null, false, 10203, '时间有误,请重新选择');
            }

            $time = strtotime($timeStr);

            if($time > 0) {
                $where['begin_time <= ?'] = $time;
                $where['end_time >= ?']   = $time;
            }
        }

        $buyDetailMapper = BuyDetailMapper::getInstance();
//        $models          = $buyDetailMapper->group($where, null, 'sparring_buy_id', 'begin_time', $limit, $offset);
        $models          = $buyDetailMapper->group($where, null, 'sparring_buy_id', 'id DESC', $limit, $offset);

        if(empty($models)) {
            return $this->response([]);
        }

        $memberMapper = MemberMapper::getInstance();
        $buyMapper    = BuyMapper::getInstance();
        $gameMapper   = GameMapper::getInstance();

        foreach($models as $model) {
            $arr                  = $model->toArray();
            $arr['time_interval'] = date('H:i', $model->getBegin_time()) . '-' . date('H:i', $model->getEnd_time());
            $buyId                = $model->getSparring_buy_id();
            $sprBuyModel          = $buyMapper->findById($buyId);

            if(!$sprBuyModel instanceof \SparringBuysModel) {
                continue;
            }

            $memberModel = $memberMapper->findById($sprBuyModel->getUid());

            if(!$memberModel instanceof \MemberModel) {
                $arr['nickname'] = '';
                $arr['avatar']   = '';
            } else {
                $arr['nickname'] = urldecode($memberModel->getNick_name());
                $arr['avatar']   = $memberModel->getAvatar();
            }

            $gameModel = $gameMapper->findById($model->getGame_id());

            if(!$gameModel instanceof \SparringGameModel) {
                $arr['game_name'] = '';
            } else {
                $arr['game_name'] = $gameModel->getGame_name();
            }

            $return[] = $arr;
        }

        return $this->response($return);
    }

    /**
     * @desc 看大腿发布接口
     *
     * @return false
     */
    public function addAction() {
        $request    = $this->getRequest();
        $uid        = $this->uid();
        $gameId     = (int)$request->get('game_id');
        $price      = (float)$request->get('price', 0.00);
        $beginTime  = (string)$request->get('begin_time');
        $endTime    = (string)$request->get('end_time');
        $gameLevel  = (string)$request->get('game_level');
        $gameServer = (string)$request->get('game_server');
        $manifesto  = (string)$request->get('manifesto');
        $buyIds     = [];

        if($price <= 0) {
            return $this->response(null, false, 10202, '价格数字有误');
        }

        if(empty($beginTime)) {
            return $this->response(null, false, 10203, '开始时间不能为空');
        }

        if(empty($endTime)) {
            return $this->response(null, false, 10204, '结束时间不能为空');
        }

        $beginTimeArr = explode(' ', $beginTime);

        if($beginTimeArr[0] === '今天') {
            $beginTimeStr = date("Y-m-d") . ' ' . $beginTimeArr[1];
            $beginTime    = strtotime($beginTimeStr);
        } elseif($beginTimeArr[0] === '明天') {
            $beginTimeStr = date("Y-m-d", strtotime("+1 day")) . ' ' . $beginTimeArr[1];
            $beginTime    = strtotime($beginTimeStr);
        } else {
            return $this->response(null, false, 10203, '开始时间有误,请重新选择');
        }

        $endTimeArr = explode(' ', $endTime);

        if($endTimeArr[0] === '今天') {
            $endTimeStr = date("Y-m-d") . ' ' . $endTimeArr[1];
            $endTime    = strtotime($endTimeStr);
        } elseif($endTimeArr[0] === '明天') {
            $endTimeStr = date("Y-m-d", strtotime("+1 day")) . ' ' . $endTimeArr[1];
            $endTime    = strtotime($endTimeStr);
        } else {
            return $this->response(null, false, 10203, '结束时间有误,请重新选择');
        }

        if($endTime <= $beginTime) {
            return $this->response(null, false, 10219, '结束时间不能小于开始时间');
        }

        if($beginTime < time() + 600) {
            return $this->response(null, false, 10219, '开始时间至少为当前时间10分钟后');
        }

        if($endTime > time() + \Lib\Consts::EXPIRE_1DAY + 600) {
            return $this->response(null, false, 10219, '只能发布24小时内信息');
        }

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return $this->response(null, false, 50000, '无效的uid');
        }

        // 同一用户同一时间段只能发布一条信息
        $buyMapper       = BuyMapper::getInstance();
        $buyDetailMapper = BuyDetailMapper::getInstance();

        $buyModels = $buyMapper->fetchAll([
            'uid'           => $uid,
            'end_time >= ?' => time(),
            //  预留时间判断
        ]);

        if(!empty($buyModels)) {
            foreach($buyModels as $buyModel) {
                $buyIds[] = $buyModel->getId();
            }
        }

        if(!empty($buyIds)) {
            $buyDetailModels = $buyDetailMapper->fetchAll([
                'sparring_buy_id' => $buyIds,
                'status'          => [\Lib\Consts::SPARRING_DETAIL_STATUS_PAY, \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL]
                // 时间需判断
            ]);
        }

        if(!empty($buyDetailModels)) {
            foreach($buyDetailModels as $buyDetailModel) {
                if(!$buyDetailModel instanceof \SparringBuyDetailModel) {
                    continue;
                }

                $detailBeginTime = $buyDetailModel->getBegin_time();
                $detailEndTime   = $buyDetailModel->getEnd_time();

                if($detailBeginTime <= $beginTime && $detailEndTime > $beginTime) {
                    return $this->response(null, false, 10220, '当前时间区段中含有已发布信息');
                }

                if($detailBeginTime < $endTime && $detailEndTime >= $endTime) {
                    return $this->response(null, false, 10220, '当前时间区段中含有已发布信息');
                }

                if($detailBeginTime >= $beginTime && $detailEndTime <= $endTime) {
                    return $this->response(null, false, 10220, '当前时间区段中含有已发布信息');
                }
            }
        }

        $buyModel = new \SparringBuysModel();
        $buyModel->setUid($uid);
        $buyModel->setBegin_time($beginTime);
        $buyModel->setEnd_time($endTime);
        $buyModel->setAdd_time(time());
        $buyModel->setStatus(\Lib\Consts::SPARRING_BUY_STATUS_NORMAL);

        $buyMapper->begin();

        try {
            $buyId = $buyMapper->insert($buyModel);
        } catch(\Exception $e) {
            $buyId = 0;
        }

        if($buyId <= 0) {
            $buyMapper->rollback();
            return $this->response(null, false, 10212, '发布失败, 请重试');
        }

        // 时间区段
        $timeInterval   = $this->getTimeInterval($beginTime, $endTime);
        $sprDetailModel = new \SparringBuyDetailModel();

        foreach($timeInterval as $value) {
            $sprDetailModel->setSparring_buy_id($buyId);
            $sprDetailModel->setBegin_time($value[0]);
            $sprDetailModel->setEnd_time($value[1]);
            $sprDetailModel->setGame_id($gameId);
            $sprDetailModel->setPrice($price);
            $sprDetailModel->setGame_level($gameLevel);
            $sprDetailModel->setGame_server($gameServer);
            $sprDetailModel->setManifesto($manifesto);
            $sprDetailModel->setGender($memberModel->getGender());
            $sprDetailModel->setStatus(\Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL);
            $sprDetailModel->setAdd_time(time());

            try {
                $lastId = $buyDetailMapper->insert($sprDetailModel);
            } catch(\Exception $e) {
                $lastId = 0;
            }

            if($lastId <= 0) {
                $buyMapper->rollback();
                return $this->response([], false, 10213, '发布详情数据失败, 请重试');
            }
        }

        $buyMapper->commit();
        return $this->response(null);
    }

    /**
     * @desc 编辑看大腿发布信息
     *
     * @return false
     */
    public function publishEditAction() {
        $request    = $this->getRequest();
        $uid        = $this->uid();
        $buyId      = (int)$request->get('buy_id');
        $gameId     = (int)$request->get('game_id');
        $netBar     = (string)$request->get('net_bar');
        $price      = (float)$request->get('price', 0.00);
        $gameLevel  = (string)$request->get('game_level');
        $gameServer = (string)$request->get('game_server');
        $manifesto  = (string)$request->get('manifesto');

        if($buyId <= 0) {
            return $this->response(null, false, 10208, '看大腿id值有误');
        }

        $buyMapper = BuyMapper::getInstance();
        $model     = $buyMapper->fetch(['uid' => $uid, 'id' => $buyId]);

        if(!$model instanceof \SparringBuysModel) {
            return $this->response(null, false, 10211, 'Invalid BuyId');
        }

        if($price <= 0) {
            return $this->response(null, false, 10202, '价格数字有误');
        }

        $buyDetailMapper = BuyDetailMapper::getInstance();
        $detailModels    = $buyDetailMapper->fetchAll([
            'sparring_buy_id' => $buyId,
            'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL,
            'begin_time > ?'  => time(),
        ]);

        if(empty($detailModels)) {
            return $this->response(null, false, 10211, 'Invalid BuyId');
        }

        $data = [
            'game_id'     => $gameId,
            'net_bar'     => $netBar,
            'price'       => $price,
            'game_level'  => $gameLevel,
            'game_server' => $gameServer,
            'manifesto'   => $manifesto,
            'update_time' => time(),
        ];

        try {
            $rows = $buyDetailMapper->update($data, [
                'sparring_buy_id' => $buyId,
                'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL,
                'begin_time > ?'  => time(),
            ]);
            return $rows > 0 ? $this->response(null) : $this->response(null, false, 10228, '看大腿信息编辑失败');
        } catch(\Exception $exc) {
            return $this->response(null, false, 10100, '异常信息报错');
        }
    }

    /**
     * @desc 看大腿发布的信息详情
     *
     * @return false
     */
    public function detailAction() {
        $request = $this->getRequest();
        $buyId   = (int)$request->get('id', 0);
        $ownUid  = $this->uid();

        if(empty($buyId)) {
            return $this->response(null, false, 10208, '看大腿id值有误');
        }

        $buyMapper = BuyMapper::getInstance();
        $model     = $buyMapper->findById($buyId);

        if(!$model instanceof \SparringBuysModel) {
            return $this->response(null, false, 10211, 'Invalid BuyId');
        }

        if($model->getEnd_time() < time()) {
            return $this->response([]);
        }

        $buyDetailMapper = BuyDetailMapper::getInstance();

        // 需求关系, 将其数据先死定为最后一个时间段的信息详情, 后续再改
        $detailModels = $buyDetailMapper->fetchAll(['sparring_buy_id' => $buyId]);

        if(empty($detailModels)) {
            return $this->response(null, false, 10208, '看大腿id值有误');
        }

        $count        = count($detailModels);
        $return       = $detailModels[$count - 1]->toArray();
        $memberMapper = MemberMapper::getInstance();
        $gameMapper   = GameMapper::getInstance();

        foreach($detailModels as $detailModel) {
            if($detailModel->getBegin_time() > time()
                && $detailModel->getStatus() === 1 || $detailModel->getStatus() === 2
            ) {
                $return['time_interval'][] = [
                    $detailModel->getId(),
                    date('H:i', $detailModel->getBegin_time()) . '-' . date('H:i', $detailModel->getEnd_time()),
                    $detailModel->getStatus(),
                ];
            }
        }

        $gameId      = $detailModels[0]->getGame_id();
        $uid         = $model->getUid();
        $memberModel = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return $this->response(null, false, 10229, 'Invalid Uid');
        }

        $avatarMapper = MemberAvatarMapper::getInstance();

        $return['uid']      = $uid;
        $return['avatar']   = array_values($avatarMapper->avatars($uid));
        $return['nickname'] = urldecode($memberModel->getNick_name());
        $return['gender']   = $memberModel->getGender();

        if(empty($memberModel->getBirthday())) {
            $return['age'] = 0;
        } else {
            $return['age'] = \Lib\Tool::age($memberModel->getBirthday());
        }

        $gameModel = $gameMapper->findById($gameId);

        if(!$gameModel instanceof \SparringGameModel) {
            $return['game_name'] = '';
        } else {
            $return['game_name'] = $gameModel->getGame_name();
        }

        $return['is_buy'] = (($uid === $ownUid) ? false : true);

        return $this->response($return);
    }

    /**
     * @desc 获取时间区段
     *
     * @param     $beginTime
     * @param     $endTime
     * @param int $interval
     * @return array
     */
    public function getTimeInterval($beginTime, $endTime, $interval = 3600) {
        $timeArr      = [];
        $timeInterval = $endTime - $beginTime;
        $num          = floor($timeInterval / $interval);
        $remainder    = $timeInterval % $interval;

        for($i = 0; $i < $num; $i++) {
            $timeArr[] = [$beginTime + $i * $interval, $beginTime + $interval * ($i + 1)];
        }

        if($remainder !== 0) {
            $timeArr[] = [$beginTime + $i * $interval, $endTime];
        }

        return $timeArr;
    }

    /**
     * @desc 看大腿搜索功能
     *
     * @return false
     */
    public function searchAction() {
        $request = $this->getRequest();
        $search  = $request->get('search', '');
        $type    = (string)$request->get('type', 'nickname');
        $page    = (int)$request->get('page', 1);
        $perPage = (int)$request->get('per_page', 15);
        $page    = max(1, $page);
        $perPage = min(30, $perPage);
        $limit   = $perPage;
        $offset  = $limit * ($page - 1);
        $ids     = [];
        $return  = [];

        if(empty($search)) {
            return $this->response(null, false, 10210, '搜索文字不能为空');
        }

        $buyMapper    = BuyMapper::getInstance();
        $memberMapper = MemberMapper::getInstance();

        if($type === 'nickname') {
            $search      = urlencode($search);
            $memberModel = $memberMapper->findByNick_name($search);

            if(!$memberModel instanceof \MemberModel) {
                return $this->response([]);
            }

            $uid = $memberModel->getId();
        } elseif($type === 'uid') {
            $uidStr = strlen($search);

            if((int)$search < 65535 || $uidStr < 5 || $uidStr > 10) {
                return $this->response([]);
            }

            $memberModel = $memberMapper->findById($search);

            if(!$memberModel instanceof \MemberModel) {
                return $this->response([]);
            }

            $uid = $search;
        } else {
            return $this->response(null, false, 10222, '搜索类型有误');
        }

        $sprBuyModels = $buyMapper->fetchAll([
            'uid'          => $uid,
            'end_time > ?' => time(),
        ], 'add_time DESC', $limit, $offset);

        if(empty($sprBuyModels)) {
            return $this->response([]);
        }

        foreach($sprBuyModels as $sprBuyModel) {
            $ids[] = $sprBuyModel->getId();
        }

        $buyDetailMapper    = BuyDetailMapper::getInstance();
        $sprBuyDetailModels = $buyDetailMapper->group([
            'sparring_buy_id' => $ids,
            'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL,
            'begin_time > ?'  => time(),
        ], null, 'sparring_buy_id', 'begin_time', $limit, $offset);

        if(empty($sprBuyDetailModels)) {
            return $this->response([]);
        }

        $memberMapper = MemberMapper::getInstance();

        foreach($sprBuyDetailModels as $sprBuyDetailModel) {
            $arr                  = $sprBuyDetailModel->toArray();
            $arr['time_interval'] = date('H:i', $sprBuyDetailModel->getBegin_time()) . '-' . date('H:i', $sprBuyDetailModel->getEnd_time());
            $memberModel          = $memberMapper->findById($uid);

            if(!$memberModel instanceof \MemberModel) {
                $arr['nickname'] = '';
            }

            $arr['nickname'] = urldecode($memberModel->getNick_name());
            $return[]        = $arr;
        }

        return $this->response($return);
    }

    /**
     * @desc 我的发布-看大腿列表
     */
    public function mylistAction() {
        $request = $this->getRequest();
        $uid     = $this->uid();
        $page    = (int)$request->get('page', 1);
        $perPage = (int)$request->get('per_page', 10);
        $page    = max(1, $page);
        $perPage = min(30, $perPage);
        $limit   = $perPage;
        $offset  = $limit * ($page - 1);

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return $this->response([], false, 50000, '无效的uid');
        }

        $buyMapper = BuyMapper::getInstance();
        // 排序按照开始时间倒序
        $sprBuyModels = $buyMapper->fetchAll(['uid' => $uid], 'begin_time DESC', $limit, $offset);
        $return       = [];

        if(empty($sprBuyModels)) {
            return $this->response([]);
        }

        $detailMapper = BuyDetailMapper::getInstance();
        $gameMapper   = GameMapper::getInstance();

        foreach($sprBuyModels as $sprBuyModel) {
            $detailModel = $detailMapper->fetch([
                'sparring_buy_id' => $sprBuyModel->getId(),
                'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL,
            ]);

            if(!$detailModel instanceof \SparringBuyDetailModel) {
                continue;
            }

            $data                  = $detailModel->toArray();
            $data['time_interval'] = date('H:i', $sprBuyModel->getBegin_time()) . '-' . date('H:i', $sprBuyModel->getEnd_time());
            $date                  = date('m月d日', $sprBuyModel->getAdd_time());

            $gameModel = $gameMapper->findById($detailModel->getGame_id());

            if(!$gameModel instanceof \SparringGameModel) {
                $data['game_name'] = '';
            } else {
                $data['game_name'] = $gameModel->getGame_name();
            }

            $tmp['date']   = $date;
            $tmp['data'][] = $data;

            if(isset($return[$date])) {
                $return[$date]['data'][] = $data;
            } else {
                $return[$date] = $tmp;
            }

            unset($tmp);
        }

        if(isset($return)) {
            $return = array_values($return);
        }

        return $this->response($return);
    }

    /**
     * @desc  我的发布-看大腿信息删除(删除看大腿消息 + 删除看大腿详情的
     * @return false
     */
    public function mydelAction() {
        $request = $this->getRequest();
        $uid     = $this->uid();
        $buyId   = (int)$request->get('id', 0);

        $buyMapper = BuyMapper::getInstance();
        $model     = $buyMapper->fetch(['id' => $buyId, 'uid' => $uid]);

        if(!$model instanceof \SparringBuysModel) {
            return $this->response(null, false, 10205, '看大腿信息id不存在');
        }

        $buyDetailMapper = BuyDetailMapper::getInstance();

        $detailModel = $buyDetailMapper->fetch([
            'sparring_buy_id' => $buyId,
            'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL]);

        if(!$detailModel instanceof \SparringBuyDetailModel) {
            return $this->response(null, false, 10215, '看大腿信息不存在');
        }

        $buyMapper->begin();
        $data = [
            'status' => \Lib\Consts::SPARRING_BUY_STATUS_DEL,
        ];
        $rows = $buyMapper->update($data, [
            'id'     => $buyId,
            'uid'    => $uid,
            'status' => \Lib\Consts::SPARRING_BUY_STATUS_NORMAL,
        ]);

        if($rows <= 0) {
            $buyMapper->rollback();
            return $this->response(null, false, 50000, '更新看大腿状态失败');
        }

        $rows = $buyDetailMapper->update(
            ['status' => \Lib\Consts::SPARRING_DETAIL_STATUS_DEL],
            [
                'sparring_buy_id' => $buyId,
                'status'          => \Lib\Consts::SPARRING_DETAIL_STATUS_NORMAL,
            ]);

        if($rows <= 0) {
            $buyMapper->rollback();
            return $this->response(null, false, 50000, '更新看大腿详情状态失败');
        }

        $buyMapper->commit();
        return $this->response(null);
    }

    /**
     * @desc 陪练游戏
     * @return false
     */
    public function gamelistAction() {
        $mapper = GameMapper::getInstance();
        $models = $mapper->fetchAll(null, 'order DESC, id', 50);

        if(empty($models)) {
            return $this->response([]);
        }

        return $this->response($models);
    }

//    /**
//     * @desc 陪练游戏--筛选
//     * @return false
//     */
//    public function selgamelistAction() {
//        $mapper = GameMapper::getInstance();
//        $models = $mapper->fetchAll(['status' => 1], 'order DESC, id', 15);
//
//        if(empty($models)) {
//            return $this->response([]);
//        }
//
//        return $this->response($models);
//    }

}
